package com.imooc.sso.server;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
import org.springframework.util.PropertyPlaceholderHelper;
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

/**
 * 该类是私有的，所以拷贝一份出来
 */
public class SsoSpelView implements View {

    private final String template;

    private final String prefix;

    private final ExpressionParser parser = new SpelExpressionParser();

    private final StandardEvaluationContext context = new StandardEvaluationContext();

    private PlaceholderResolver resolver;

    SsoSpelView(String template) {
        this.template = template;
        this.prefix = new RandomValueStringGenerator().generate() + "{";// xxxx{
        this.context.addPropertyAccessor(new MapAccessor());
        this.resolver = name -> {
            Expression expression = parser.parseExpression(name);
            Object value = expression.getValue(context);
            return value == null ? null : value.toString();
        };
    }

    /*public static void main(String[] args) {
        Account account = new Account("Deniro");
        ExpressionParser parser = new SpelExpressionParser();
        EvaluationContext context = new StandardEvaluationContext(account);
        Expression expression = parser.parseExpression("name");
        String result = expression.getValue(context, String.class);
        System.out.println("result:" + result);
    }

    public static class Account {

        private String name;

        public Account(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }*/

    public String getContentType() {
        return "text/html";
    }

    public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, Object> map = new HashMap<>(model);
        String path = ServletUriComponentsBuilder.fromContextPath(request).build().getPath();
        map.put("path", path == null ? "" : path);
        context.setRootObject(map);
        String maskedTemplate = template.replace("${", prefix);// xxxx{
        PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper(prefix, "}");
        String result = helper.replacePlaceholders(maskedTemplate, resolver);
        result = result.replace(prefix, "${");
        response.setContentType(getContentType());
        response.getWriter().append(result);
    }

    /*public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("123", " 444 ");
        map.put("356", " 555 ");

        String s = "aaaaabbbb${123}xxxx${356}vvv";
        PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
        String result = helper.replacePlaceholders(s, map::get);
        System.out.println(result);
    }*/
}
